package com.jy.datapipeline.importserver.support;

import com.jy.datapipeline.common.constants.PrefixConstants;
import com.jy.datapipeline.importserver.handler.ScheduleRetrySubtaskHandler;
import com.jy.datapipeline.importserver.handler.ScheduleTaskHandler;
import com.mysql.cj.util.StringUtils;
import org.quartz.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;

/**
 * @类名 QuartzSupport
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2023/6/25 22:55
 * @版本 1.0
 */
@Component
public class QuartzSupport {

    @Resource
    private Scheduler scheduler;

    public void createScheduledTask(String taskId, String cornTab, Date nextStartTime) throws SchedulerException {
        //创建任务实例
        JobDetail jobDetail = JobBuilder.newJob(ScheduleTaskHandler.class).withIdentity(taskId, "import_task").build();
        jobDetail.getJobDataMap().put("id", taskId);

        //通过指定开始时间和cron表达式,创建触发器
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(taskId)
                .startAt(nextStartTime)
                .withSchedule(CronScheduleBuilder.cronSchedule(cornTab).withMisfireHandlingInstructionDoNothing())
                .build();
        //关联触发器和任务
        scheduler.scheduleJob(jobDetail, trigger);
    }

    public void updateScheduledTask(String taskId, Date nextStartTime, String cornTab) throws SchedulerException {
        //重新修改定时任务
        TriggerKey triggerKey = TriggerKey.triggerKey(taskId);
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        cronTrigger = cronTrigger.getTriggerBuilder()
                .withIdentity(taskId)
                .startAt(nextStartTime)
                .withSchedule(CronScheduleBuilder.cronSchedule(cornTab).withMisfireHandlingInstructionDoNothing())
                .build();
        scheduler.rescheduleJob(triggerKey, cronTrigger);
        scheduler.pauseTrigger(triggerKey);
    }

    public boolean isEmpty(Long subtaskId) throws SchedulerException {
        String key = PrefixConstants.SUBTASK_PREFIX + "_" + subtaskId;
        SimpleTrigger simpleTrigger = (SimpleTrigger) scheduler.getTrigger(TriggerKey.triggerKey(key));
        JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(key, "import_subtask"));
        return simpleTrigger == null && jobDetail == null;
    }

    public void createRetryScheduledTask(Date startTime, Long subtaskId, Integer trySubtaskLoadCount, Integer trySubtaskLoadInterval) throws SchedulerException {
        if (this.isEmpty(subtaskId)) {
            String identity = PrefixConstants.SUBTASK_PREFIX + "_" + subtaskId;

            JobDetail jobDetail = JobBuilder.newJob(ScheduleRetrySubtaskHandler.class)
                    .withIdentity(identity, "import_subtask").build();

            JobDataMap jobDataMap = jobDetail.getJobDataMap();
            jobDataMap.put("id", subtaskId);
            jobDataMap.put("trySubtaskLoadCount", trySubtaskLoadCount);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startTime);
            calendar.add(Calendar.MINUTE, trySubtaskLoadInterval);

            SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(identity)
                    .startAt(calendar.getTime())
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInMinutes(trySubtaskLoadInterval).repeatForever())
                    .build();

            scheduler.scheduleJob(jobDetail, simpleTrigger);
        }
    }

    public void delete(String identity, String group) throws SchedulerException {
        JobKey jobKey;
        if (!StringUtils.isNullOrEmpty(group)) {
            jobKey = JobKey.jobKey(identity, group);
        } else {
            jobKey = JobKey.jobKey(identity);
        }
        scheduler.deleteJob(jobKey);
    }

    public boolean isPaused(String key) throws SchedulerException {
        Trigger.TriggerState triggerState = scheduler.getTriggerState(TriggerKey.triggerKey(key));
        return triggerState == Trigger.TriggerState.PAUSED;
    }

    public void pause(String key) throws SchedulerException {
        scheduler.pauseTrigger(TriggerKey.triggerKey(key));
    }
}
